/*
 * Copyright 2018 requery.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.requery.android.sqlite

import android.annotation.SuppressLint
import java.sql.ResultSet
import java.sql.SQLException
import java.sql.Statement

/**
 * [java.sql.Statement] implementation using Android's local SQLite database.
 *
 * @author Nikhil Purushe
 */
internal class SqliteStatement(protected val sqliteConnection: SqliteConnection)
    : BaseStatement(sqliteConnection) {

    @Throws(SQLException::class)
    override fun execute(sql: String, autoGeneratedKeys: Int): Boolean {
        try {
            sqliteConnection.database.compileStatement(sql).use({ statement ->
                if (autoGeneratedKeys == Statement.RETURN_GENERATED_KEYS) {
                    val rowId = statement.executeInsert()
                    insertResult = SingleResultSet(this, rowId)
                    return true
                } else {
                    statement.execute()
                }
            })
        } catch (e: android.database.SQLException) {
            BaseConnection.throwSQLException(e)
        }

        return false
    }

    @Throws(SQLException::class)
    override fun executeQuery(sql: String): ResultSet? {
        throwIfClosed()
        try {
            @SuppressLint("Recycle") // released with the queryResult
            val cursor = sqliteConnection.database.rawQuery(sql, null)
            queryResult = CursorResultSet(this, cursor, true)
            return queryResult
        } catch (e: android.database.SQLException) {
            BaseConnection.throwSQLException(e)
        }

        return null
    }

    @Throws(SQLException::class)
    override fun executeUpdate(sql: String, autoGeneratedKeys: Int): Int {
        try {
            sqliteConnection.database.compileStatement(sql).use({ statement ->
                if (autoGeneratedKeys == Statement.RETURN_GENERATED_KEYS) {
                    val rowId = statement.executeInsert()
                    insertResult = SingleResultSet(this, rowId)
                    updateCount = 1
                } else {
                    updateCount = statement.executeUpdateDelete()
                }
            })
        } catch (e: android.database.SQLException) {
            BaseConnection.throwSQLException(e)
        }

        return updateCount
    }
}
